package br.com.lh.urabuilder.view.arrow
{
	import br.com.lh.urabuilder.domain.view.UraElement;
	import br.com.lh.urabuilder.domain.xml.UraActionWithNext;
	import br.com.lh.urabuilder.model.UraModelLocator;
	import br.com.lh.urabuilder.util.BorderDrawer;
	import br.com.lh.urabuilder.util.CoordinatesUtils;
	import br.com.lh.urabuilder.view.ActionComponent;
	import br.com.lh.urabuilder.view.arrow.drawer.ArrowContainerDrawer;
	import br.com.lh.urabuilder.view.arrow.drawer.IArrowContainerDrawer;
	
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import mx.collections.ArrayCollection;
	import mx.containers.Canvas;
	[Bindable]

	public class ArrowContainer extends Canvas implements UraElement, IArrowContainer
	{
		public var startPoint:Point;
		public var endPoint:Point;
		private var _selected:Boolean=false;
		private var arrowContainerDrawer:IArrowContainerDrawer;
		private var _startComponent:ActionComponent;
		private var _endComponent:ActionComponent;
		private var arrowWrapper:ArrowWrapper=null;
		public static const END_OF_ARROW_PERCENT:Number=0.7;
		public static const START_OF_ARROW_PERCENT:Number=0.3;
		public static const OFFSET_SELF_ARROW_HEIGHT:int=10;
		public static const HALF_CONTAINER_HEIGHT:Number=10;

		public function ArrowContainer(startPoint:Point, endPoint:Point)
		{
			this.horizontalScrollPolicy="off";
			this.verticalScrollPolicy="off";
			doDraw(startPoint, endPoint);
			addListeners();
		}

		public function doDraw(startPoint:Point, endPoint:Point):void
		{
			scaleX=UraModelLocator.getInstance().zoomManager.currentScale;
			scaleY=UraModelLocator.getInstance().zoomManager.currentScale;
			setBasicValues(startPoint, endPoint);
			arrowContainerDrawer=new ArrowContainerDrawer(startPoint, endPoint);
			setDimensions(arrowContainerDrawer);
			arrowWrapper=arrowContainerDrawer.arrowWrapper;
			addChild(arrowWrapper);
			rotation=CoordinatesUtils.getAngleInDegrees(startPoint, endPoint);
		}

		public function selectObject(event:MouseEvent):void
		{
			UraModelLocator.getInstance().viewManager.selectComponent(this, true, event.shiftKey);
			UraModelLocator.getInstance().mouseEventHelper.mouseReleased();
		}

		private function setDimensions(arrowContainerDrawer:IArrowContainerDrawer):void
		{
			var initialPoint:Point=arrowContainerDrawer.initialPoint;
			this.x=initialPoint.x;
			this.y=initialPoint.y;
			this.width=arrowContainerDrawer.width;
			this.height=arrowContainerDrawer.height;
		}

		private function setBasicValues(startPoint:Point, endPoint:Point):void
		{
			this.startPoint=startPoint;
			this.endPoint=endPoint;
		}

		public function removeWrapper():void
		{
			removeChild(arrowWrapper);
		}

		private function addListeners():void
		{
			addEventListener(MouseEvent.MOUSE_UP, selectObject);
			addEventListener(MouseEvent.MOUSE_DOWN, UraModelLocator.getInstance().arrowRotateHelper.mouseDown);
		}

		public function remove():void
		{
			if (arrowIsBoundOnStart() && startComponent.uraAction is UraActionWithNext)
			{
				var startAction:UraActionWithNext=UraActionWithNext(startComponent.uraAction);
				startAction.setNextId(-1);
				UraModelLocator.getInstance().xmlManager.unlinkElement(startAction);
			}
			arrowWrapper.remove();
			if (arrowIsBoundOnStart())
			{
				doRemove(startComponent.outArrows);
			}
			if (arrowIsBoundOnEnd())
			{
				doRemove(endComponent.entryArrows);
			}
		}

		public function arrowIsBoundOnStart():Boolean
		{
			return startComponent != null;
		}

		public function arrowIsBoundOnEnd():Boolean
		{
			return endComponent != null;
		}


		private function doRemove(arrows:ArrayCollection):void
		{
			var index:Number=arrows.getItemIndex(this);
			if (index != -1)
			{
				arrows.removeItemAt(index);
			}
		}

		public function set startComponent(startComponent:ActionComponent):void
		{
			this._startComponent=startComponent;
			startComponent.addOutArrow(this);
		}

		public function set endComponent(endComponent:ActionComponent):void
		{
			this._endComponent=endComponent;
			endComponent.addEntryArrow(this);
		}

		public function get startComponent():ActionComponent
		{
			return _startComponent;
		}

		public function get endComponent():ActionComponent
		{
			return _endComponent;
		}

		public function get selfArrow():Boolean
		{
			return false;
		}

		public function get selected():Boolean
		{
			return _selected;
		}

		public function set selected(selected:Boolean):void
		{
			this._selected=selected;
			BorderDrawer.drawBorder(this, selected);
		}

		public function children():ArrayCollection
		{
			return new ArrayCollection;
		}
	}
}


